package com.example.matchingengine.model;

import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单模型类
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Order {
    
    /**
     * 订单ID
     */
    private String id;
    
    /**
     * 交易对
     */
    private String symbol;
    
    /**
     * 订单方向：BUY, SELL
     */
    private OrderSide side;
    
    /**
     * 订单类型：LIMIT, MARKET
     */
    private OrderType type;
    
    /**
     * 订单执行策略：GTC, IOC, FOK
     */
    private TimeInForce timeInForce;
    
    /**
     * 价格
     */
    private BigDecimal price;
    
    /**
     * 数量
     */
    private BigDecimal quantity;
    
    /**
     * 已成交数量
     */
    private BigDecimal filledQuantity;
    
    /**
     * 订单状态
     */
    private OrderStatus status;
    
    /**
     * 用户ID
     */
    private String userId;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    /**
     * 订单方向枚举
     */
    public enum OrderSide {
        BUY, SELL
    }
    
    /**
     * 订单类型枚举
     */
    public enum OrderType {
        LIMIT, MARKET
    }
    
    /**
     * 订单执行策略枚举
     */
    public enum TimeInForce {
        GTC,  // Good Till Cancel - 限价单默认策略，未成交部分加入订单簿
        IOC,  // Immediate or Cancel - 立即成交，未成交部分取消
        FOK   // Fill or Kill - 全部成交或全部取消
    }
    
    /**
     * 订单状态枚举
     */
    public enum OrderStatus {
        NEW, PARTIALLY_FILLED, FILLED, CANCELED, REJECTED, PARTIALLY_FILLED_CANCELED
    }
    
    /**
     * 重置订单对象（用于对象池回收复用）
     */
    public void reset() {
        this.id = null;
        this.symbol = null;
        this.side = null;
        this.type = null;
        this.timeInForce = null;
        this.price = null;
        this.quantity = null;
        this.filledQuantity = null;
        this.status = null;
        this.userId = null;
        this.createTime = null;
        this.updateTime = null;
    }
}